package org.naxx.security.expression.impl;

import java.util.ArrayList;
import java.util.List;

import org.naxx.security.Main;
import org.naxx.security.common.UuidGen;
import org.naxx.security.expression.Node;
import org.naxx.security.function.FunctionType;
import org.naxx.security.model.match.AttributeDesignator;
import org.naxx.security.model.match.ValueHolder;

public class NodeImpl implements Node {
	
	private String id;
	private NodeType nodeType;
	private Node parent;
	private List<Node> children;
	private Node nextSibiling;
	
	// following three field are exclusive, only one can
	// be not null
	private AttributeDesignator attributeDesignator;
	private ValueHolder valueHolder;
	private FunctionType functionType;
	
	public NodeImpl() {
		this.id = Main.getRepository().getService(UuidGen.class).getRandomUuid();
		this.children = new ArrayList<Node>();
	}
	
	public NodeImpl(NodeType nodeType, Node parent, List<Node> children, ValueHolder valueHolder, 
			FunctionType functionType, AttributeDesignator attributeDesignator) {
		
		this.id = Main.getRepository().getService(UuidGen.class).getRandomUuid();
		this.nodeType = nodeType;
		this.attributeDesignator = attributeDesignator;
		this.valueHolder = valueHolder;
		this.functionType = functionType;
		this.parent = parent;
		this.children = children;
	}

	public AttributeDesignator getAttributeDesignator() {
		return this.attributeDesignator;
	}

	public List<Node> getChildren() {
		return this.children;
	}

	public FunctionType getFunctionType() {
		return this.functionType;
	}

	public NodeType getNodeType() {
		return this.nodeType;
	}

	public Node getParent() {
		return this.parent;
	}

	public ValueHolder getValueHolder() {
		return this.valueHolder;
	}

	public void setAttributeDesignator(AttributeDesignator attributeDesignator) {
		this.attributeDesignator = attributeDesignator;
	}

	public void setFunctionType(FunctionType functionType) {
		this.functionType = functionType;
	}

	public void setNodeType(NodeType nodeType) {
		this.nodeType = nodeType;
	}

	public void setParent(Node parent) {
		this.parent = parent;
	}

	public void setValueHolder(ValueHolder valueHolder) {
		this.valueHolder = valueHolder;
	}
	
	public void addChild(Node child) {
		this.children.add(child);
	}

	public Node getSibling() {
		return this.nextSibiling;
	}
	public void setSibiling(Node nextSibiling) {
		this.nextSibiling = nextSibiling;
	}
	
	public String getId() {
		return id;
	}	
}
